#ifndef TIMER_H
#define	TIMER_H

#include <ctime>
#include "Thread.h"

using namespace TP;
using namespace TP::Threading;

namespace TP { namespace Temporizador {

typedef enum {ASCENDENTE, DESCENDENTE, RELOJ} timer_modo_t;

typedef int tiempo_t;

// Esta indica como hace el conteo, de 1 en 1, 2 en 2, etc.
const double salto_tiempo = 1;

class Timer : public Thread {
public:
    
    // Crea un timer en modo RELOJ.
    Timer();
    
    /**
     * Crea un timer con datos pasados por el usuario.
     * @param tiempo Valor Cantidad límite de segundos que cuenta el timer.
     * @param modo Tipo de conteo que realiza el timer:
     * ASCENDENTE: 0..segundos.
     * DESCENDENTE: segundo..0.
     * RELOJ: 0..inf.
     */
    Timer(const tiempo_t &segundos, const timer_modo_t &modo);

    /**
     * Método que se va a ejecutar asincrónicamente en el thread.
     * Actualiza constantemente el estado del timer.
     */
    virtual void tarea();
    
    /**
     * Setea la cantidad de segundos que va a contar el timer.
     * Solo en los modos ASCENDENTE y DESCENDENTE.
     * @param tiempo Segundos que va a contar el timer.
     */
    void setTiempo(const tiempo_t &segundos);
    
    /**
     * Setea el modo en el que va a operar el timer.
     * @param modo Modo en el que va a operar el timer.
     */
    void setModo(const timer_modo_t &modo);
    
    /**
     * @return Retorna true si el timer completó su conteo; de lo contarrio,
     * retorna false.
     */
    bool timeOut() const;
    
    /**
     * Configura el timer para empezar a contar.
     * Este método debe ser llamado antes de comenzar a utilizarlo.
     */
    void prender();
    
    /**
     * Apaga el timer ¬¬.
     */
    void apagar();
    
    // Resetea el timer a su conteo inicial.
    void resetear();
    
    // Retorna el tiempo contado actualmente por el timer.
    tiempo_t getTiempo();
    
    // Destructor.
    virtual ~Timer();
    
private:
    
    bool __compAscendente();
    
    bool __compDescendente();
    
    bool __compReloj();
    
    bool __comparar();
private:
    tiempo_t _tiempoLimite;
    tiempo_t _tiempoActual;
    timer_modo_t _modo;
    time_t _ti, _tf;
    tiempo_t _deltaTiempo;
    bool _encendido;
};

}}

#endif	/* TIMER_H */

